package com.hbwxz.utils;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * 事务工具类
 * <p>
 * 场景：在一个方法里边儿执行业务逻辑，执行完之后推送 MQ，这里就会产生一个问题，推送 MQ 成功了，但是业务代码抛异常了导致回滚，这个时候推送 MQ 的操作是不可逆的，这就需要我们在业务代码成功
 * 执行之后再去推送 MQ 的一个操作；
 *
 * @author shenzw
 * @date 2023/12/10
 */
public class TransactionUtils {

    public static void doAfterTransaction(DoTransactionCompletion doTransactionCompletion) {
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(doTransactionCompletion);
        }
    }

    /**
     * 方法演示
     */
    @Transactional(rollbackFor = Exception.class)
    public void doTx() {
        // 开启事务
        System.out.println("Tx start...");

        // 监听事务是否成功提交
        TransactionUtils.doAfterTransaction(new DoTransactionCompletion(() -> {
            // 推送 MQ
        }));

        // 结束事务
        System.out.println("Tx end...");
    }
}


class DoTransactionCompletion implements TransactionSynchronization {

    private final Runnable runnable;

    public DoTransactionCompletion(Runnable runnable) {
        this.runnable = runnable;
    }

    @Override
    public void afterCompletion(int status) {
        if (status == TransactionSynchronization.STATUS_COMMITTED) {
            this.runnable.run();
        }
    }
}